package cn.pdx.elec.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.pdx.elec.dao.CommonDao;
import cn.pdx.elec.util.GenericSuperClass;

/**
 * 公共实现类
 * @author 彭定旭
 * extends ：HibernateDaoSupport
 * @param <T>
 */
public class CommonDaoImpl<T> extends HibernateDaoSupport implements CommonDao<T> {
   
	
	//每次都写这个方法，所以封装一个类
	//泛型转换
	private Class entity=GenericSuperClass.getClass(this.getClass());
	
	
	/**
	 * 采用注解把HibernateTemplate注入sessionFactory就可以自动创建sessionFactory了
	 * setSessionFactory重名了->setSessionFactoryDi
	 */
	
	@Resource(name="sessionFactory")
	public final void setSessionFactoryDi(SessionFactory sessionFactory)
	{
		super.setSessionFactory(sessionFactory);
	}
	
	/**
	 * @Name:save
	 * @Description:保存对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-24(创建日期)
	 * @parameters:T entity
	 * @return:无（有什么就写什么，么有就写无）
	 */
	public void save(T entity) {
		
		this.getHibernateTemplate().save(entity);
	}

	/**
	 * @Name:update
	 * @Description:修改对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:T entity
	 * @return:无（有什么就写什么，么有就写无）
	 */
	public void update(T entity) {

		this.getHibernateTemplate().update(entity);
	}

	/**
	 * @Name:findObjectById()
	 * @Description:通过Id查找对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:Serializable id <Serializable包含了String int 等类型的接口,实现就ok>
	 * @return:T 泛型对象
	 */
	@SuppressWarnings("unchecked")
	public T findObjectById(Serializable id) {
		
		//这里用到了泛型转换类来转换,在上面定义了
		return (T)this.getHibernateTemplate().get(entity, id);
	}

	/**
	 * @Name:deleteObjectByIds
	 * @Description:通过Ids的数组删除对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:Serializable... ids
	 * @return:无
	 */
	public void deleteObjectByIds(Serializable... ids) {
		
		//查询对象出来
		for(int i=0;ids!=null && i<ids.length;i++)
		{
			Serializable id=ids[i];
			
			//获取对象
			Object object=this.getHibernateTemplate().get(entity, id);
			
			this.getHibernateTemplate().delete(object);
		}
	}

	/**
	 * @Name:deleteObjectByCollection
	 * @Description:通过集合形式删除对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:Collection<T> list 集合对象
	 * @return:无
	 */
	
	public void deleteObjectByCollection(Collection<T> entities) {

		this.getHibernateTemplate().deleteAll(entities);
	}

	/**
	 * @Name:findCollectionByConditionNoPage
	 * @Description:通过查询条件查询列表；不分页
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:String hqlWhere,Object[] params, LinkedHashMap<String, String> orderby
	 * @return:结果集列表List<T>
	 */
	public List<T> findCollectionByConditionNoPage(String hqlWhere,final Object[] params, LinkedHashMap<String, String> orderby) {
		
		//底层方法不能写死,entity.getSimpleName()用泛型转换为想要的对象
		String hql="from "+ entity.getSimpleName() +" o where 1=1";
		
		//组织排序条件,抽出一个方法
		String hqlOrderBy=this.orderByCondition(orderby);
		
		hql=hql + hqlWhere + hqlOrderBy;
		
		//模板要定义为最终变量
		final String finalHql=hql;
		//System.out.println(finalHql);
		@SuppressWarnings("unchecked")
		List<T> list = (List<T>)this.getHibernateTemplate().execute(new HibernateCallback(){
			
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				
	     	Query query=session.createQuery(finalHql);
	     	  
	     	//设置参数，抽一个方法
	     	setParams(query,params);
	     	
				return query.list();
			}
	
		});
		return list;
	}
	
	
	/**
	 * @Name:setParams
	 * @Description:对where条件中的参数设置参数值
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:Object[] params
	 * @return:无
	 */
		private void setParams(Query query,Object[] params) {
			for(int i=0;params!=null && i<params.length;i++)
	     	{
	     		query.setParameter(i, params[i]);
	     	}
		}
		
		
	/**
	 * @Name:orderByCondition
	 * @Description:组织排序语句
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-3-25(创建日期)
	 * @parameters:LinkedHashMap<String, String> orderby
	 * @return:String 排序语句字符串
	 */
	private String orderByCondition(LinkedHashMap<String, String> orderby) {
		
		StringBuffer buffer=new StringBuffer("");
		if(orderby!=null)
		{
			buffer.append(" order by ");
			for(Map.Entry<String, String> map :orderby.entrySet())
			{
				
				buffer.append(" "+ map.getKey()+" "+map.getValue()+",");
			}
			//删除最后一个,
			buffer.deleteCharAt(buffer.length()-1);
		}
		return buffer.toString();
	}

	
	/**
	 * @Name:saveObjectByCollection
	 * @Description:通过一个list集合进行批量保存对象
	 * @author 彭定旭
	 * @version：v1.00（版本号）
	 * @Create Date:2013-4-2(创建日期)
	 * @parameters:Collection<T> entities 集合对象
	 * @return:无
	 */
	public void saveObjectByCollection(Collection<T> entities) {
		
		/**
		 * 调用底层方法
		 */
		this.getHibernateTemplate().saveOrUpdateAll(entities);
	}

}
